
/**
 * @ProjectName: 
 * @Copyright: 2014 lisheng  All Right Reserved.
 * @address: toughheart@163.com
 * @date: 2015年1月13日 下午3:34:37
 * @Description: 本内容未经本人允许禁止使用、转发.
 */
 
package com.ls.fw.data.search.impl.lucene.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Set;

import org.apache.lucene.document.Document;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ls.fw.data.search.impl.lucene.mapper.DocMapper;


/**
 * 
 * @author lisheng
 * @date 2015年1月13日 下午3:34:37
 * @version V1.0 
 */
public class LuceneUtil {

	private static Logger logger = LoggerFactory.getLogger(LuceneUtil.class);

	
	/**
	 * 获取最小结果数量
	 * @param page
	 * @param pageSize
	 * @param searcher
	 * @return
	 */
	public static int getMinResultSizeByPage(final int page, final int pageSize, final IndexSearcher searcher){
		int offset = (int) ((page - 1) * pageSize);
		if (offset < 0) {
			offset = 0;
		}
		return getMinResultSizeByOffset(offset, pageSize, searcher);
	}
	
	public static int getMinResultSizeByOffset(final int offset, final int pageSize, final IndexSearcher searcher){
		int maxResult = searcher.getIndexReader().maxDoc();
		int maxDoc = maxResult;
		if (pageSize > 0) {
			maxDoc = offset + pageSize;
			maxDoc = (int) Math.min(maxDoc, maxResult);
			if (maxDoc <= 0) {
				maxDoc = 1;
			}
		}
		return maxDoc;
	}


	public static <M> List<M> getResult(final int offset, final int _pageSize, IndexSearcher searcher,
			TopDocs topDocs, DocMapper<M> mapper) throws IOException {
		return getResult(offset, _pageSize, searcher, topDocs,null, mapper);
	}
	
	
	public static <M> List<M> getResult(final int _offset, final int _pageSize, IndexSearcher searcher,
			TopDocs topDocs, final Set<String> showFields, DocMapper<M> mapper) throws IOException {
		long start = System.currentTimeMillis();
		int offset = _offset;
		if(offset < 0){
			offset = 0 ;
		}
		int  pageSize = _pageSize;
		int totalCount = topDocs.totalHits;// 总记录数
		if(pageSize <= 0){
			pageSize = totalCount;
		}
		ScoreDoc[] hits = topDocs.scoreDocs;
		int count =  (int) Math.min(hits.length, pageSize);
		int length = (int) Math.min(offset + totalCount, offset + count);
		if(hits.length < length){
			length = hits.length;
		}
		int size = length - offset;
		if (size <= 0 && hits.length>0) {
			size = 1;
		}
		if(length > hits.length){
			length = hits.length;
		}
		if(offset > length){
			offset = length;
		}
		List<M> list = null;
		list = new ArrayList<M>(size);
		int row = 1;
		for (int i = offset; i < length; i++) {
			int docId = hits[i].doc;
			Document doc = null;
			if(showFields==null || showFields.isEmpty()){
				 doc = searcher.doc(docId);
			}else{
				 doc = searcher.doc(docId, showFields);
			}
			M obj = mapper.mapper(doc, row++);
			if(obj != null){
				list.add(obj);
			}
		}
		logger.info("组装记录耗时：" + (System.currentTimeMillis() - start)
				+ " ms");
		return list;
	}
	
	public static DateTime getNextDayDesc(DateTime end){
		return getNextDayDesc(end, 1);
	}
	
	public static DateTime getNextDayDesc(DateTime end,int step){
		return end.plusDays(-step);
	}
}
